﻿/* 项目“Jy.Abp.Ddd.Application (netstandard2.0)”的未合并的更改
在此之前:
using Microsoft.AspNetCore.Authorization;
在此之后:
using Jy;
using Jy.Abp;
using Jy.Abp;
using Jy.Abp.Tests;
using Microsoft.AspNetCore.Authorization;
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Jy.Abp.Extensions;
using Jy.Abp.Theading;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Localization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.EventBus.Distributed;

namespace Jy.Abp.Application;

public abstract class AppService : ApplicationService, IApplicationService
{
    protected IDistributedEventBus EventBus =>
        LazyServiceProvider.LazyGetRequiredService<IDistributedEventBus>();

    /// <summary>
    /// 并发控制器
    /// </summary>
    protected SemaphoreSlimManager SemaphoreSlimManager =>
        LazyServiceProvider.LazyGetRequiredService<SemaphoreSlimManager>();

    //public IUserCache UserCache { get; set; }
    //public ITenantCache TenantCache { get; set; }
    protected AppService()
    {
        LocalizationResource = JyAbpConsts.AppResourceType;
        //this.AsyncQueryableExecuter = NullAsync;
    }

    /// <summary>
    /// 当前登录用户ID
    /// </summary>
    protected Guid CurrentUserId {
        get {
            if (!CurrentUser.Id.HasValue)
                throw new AbpAuthorizationException(L["CurrentUserDidNotLoginToTheApplication"]);
            return CurrentUser.Id.Value;
        }
    }

    protected virtual async Task CheckAnyPolicyAsync(params string[] permissionNames)
    {
        var pns = permissionNames?
            .Where(t => !t.IsNullOrEmpty())
            .ToArray();
        if (!pns.IsNullOrEmpty())
        {
            if (!await AuthorizationService.IsGrantedAnyAsync(pns))
                throw new AbpAuthorizationException(null, AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedWithPolicyName)
                    .WithData("PolicyName", string.Join(',', pns));
        }
    }

    /// <summary>
    /// 创建分页数据创建并返回指定的Result对像
    /// </summary>
    protected virtual async Task<TPagedResultDto> CreatePagedResultAsync<T, TPagedResultDto>(
        IQueryable<T> query,
        PagedAndSortedFilter filter)
        where TPagedResultDto : PagedResultDto<T>, new()
    {
        var totalCcount = await AsyncExecuter.CountAsync(query);
        var items = await AsyncExecuter.ToListAsync(query.PageAndSortBy(filter));

        return new TPagedResultDto
        {
            Items = items,
            TotalCount = totalCcount
        };
    }

    /// <summary>
    /// 获取分页数据
    /// </summary>
    protected virtual async Task<PagedResultDto<T>> CreatePagedResultAsync<T>(
        IQueryable<T> query,
        PagedAndSortedFilter filter)
    {
        return await CreatePagedResultAsync<T, PagedResultDto<T>>(query, filter);
    }

    /// <summary>
    /// 创建分页数据返回结果，并自动从TEntity映射到TEntityDto（先返回数据再映射）
    /// </summary>
    protected virtual async Task<TPagedResultDto> CreatePagedResultMapAfterAsync<T, TDto, TPagedResultDto>(
        IQueryable<T> query,
        PagedAndSortedFilter filter)
        where TPagedResultDto : PagedResultDto<TDto>, new()
    {
        var totalCcount = await AsyncExecuter.CountAsync(query);
        var items = await AsyncExecuter.ToListAsync(query.PageAndSortBy(filter));

        return new TPagedResultDto
        {
            Items = ObjectMapper.Map<IEnumerable<T>, List<TDto>>(items),
            TotalCount = totalCcount
        };
    }

    /// <summary>
    /// 创建分页数据（先返回所有数据再映射）
    /// </summary>
    protected virtual async Task<PagedResultDto<TDto>> CreatePagedResultMapAfterAsync<T, TDto>(
        IQueryable<T> query,
        PagedAndSortedFilter filter)
    {
        return await CreatePagedResultMapAfterAsync<T, TDto, PagedResultDto<TDto>>(query, filter);
    }
}

public abstract class AppService<TEntity, TPrimaryKey> : AppService
    where TEntity : class, IEntity<TPrimaryKey>
{
    protected readonly IRepository<TEntity, TPrimaryKey> Repository;

    public AppService(IRepository<TEntity, TPrimaryKey> repository)
    {
        Repository = repository;
    }

    /// <summary>
    /// id获取实体数据 如果不存在则抛出异常
    /// </summary>
    protected virtual Task<TEntity> GetEntityByIdAsync(TPrimaryKey id)
    {
        return Repository.GetAsync(id);
    }
}

public abstract class AppService<TEntity> : AppService<TEntity, int>
   where TEntity : class, IEntity<int>
{
    public AppService(IRepository<TEntity, int> currentRepository) : base(currentRepository)
    {

    }
}

